home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1996 / MacHack 1996.toast / Hacks / Hacks ’89 / gadlife / source (ugly) / draw.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-05-14  |  17.6 KB  |  594 lines  |  [TEXT/KAHL]

  1. #include "main.h"
  2. #include "cursors.h"
  3. #include "draw.h"
  4.  
  5. extern int                isBackground;
  6. extern long            timer();
  7.  
  8. /*****************************************************************
  9. *                                                                            *
  10. *    This updates the ants pattern by shifting it to be in line with the current ticks.  It checks to    *
  11. *    see how far it would be moving them, and if it is more then three pixels, it moves it only 3.    *
  12. *    Otherwise the crawling can look either jumpy or backwards.  2 would be preferable, but        *
  13. *    during large color-screen selects it often slows down to 3 ticks.                        *
  14. *                                                                            *
  15. *****************************************************************/
  16.  
  17. Pattern *getAnts( which )
  18.     int    which;
  19.     {
  20.     static int    ants[ 2 ][ 7 ] = {{ 0x3e7c, 0xf8f1, 0xe3c7, 0x8f1f, 0x3e7c, 0xf8f1, 0xe3c7 },
  21.                         { 0x1f3e, 0x7cf8, 0xf1e3, 0xc78f, 0x1f3e, 0x7cf8, 0xf1e3 }};
  22.  
  23.     return(( Pattern* )&( ants[ which & 1 ][ 3 - which / 2 ] ));
  24.     }
  25.  
  26. int updateAnts( theData )
  27.     dataPtr        theData;
  28.     {
  29.     long            tick;
  30.     int            change;
  31.     
  32.     tick = TickCount();
  33.     change = tick - theData->antTick;
  34.     theData->antTick = tick;
  35.     if( change > maxAntDelta ) change = maxAntDelta;
  36.     theData->antSkew = ( theData->antSkew + change ) & 7;
  37.     return( change );
  38.     }
  39.  
  40. drawAnts( theData, change )
  41.     dataPtr        theData;
  42.     int            change; 
  43.     {
  44.     PenState        savePen;
  45.     GrafPtr        savePort;
  46.     RgnHandle        saveClip;
  47.     Pattern        *oldPat, *newPat, tempPat;
  48.     int            i;
  49.     
  50.     GetPort( &savePort );
  51.     SetPort( theData->parent );
  52.     GetPenState( &savePen );
  53.     oldPat = getAnts(( theData->antSkew - change ) & 7 );
  54.     newPat = getAnts( theData->antSkew );
  55.     for( i = 0; i < 8; ++i ) tempPat[ i ] = ( *oldPat )[ i ] ^ ( *newPat )[ i ];
  56.     PenPat( &tempPat );
  57.     PenMode( patXor );
  58.     PenSize( 1, 1 );
  59.     saveClip = NewRgn();
  60.     doMenuClip( saveClip );
  61.     FrameRgn( theData->selRgn );
  62.     SetClip( saveClip );
  63.     DisposeRgn( saveClip );
  64.     SetPenState( &savePen );
  65.     SetPort( savePort );
  66.     theData->changed = timer();
  67.     theData->allBitsState |= bitsBadAnts;
  68.     }
  69.  
  70. /*****************************************************************
  71. *                                                                            *
  72. *                                                                            *
  73. *****************************************************************/
  74.  
  75. dropSel( theData )
  76.     dataPtr        theData;
  77.     {
  78.     Rect            *bounds;
  79.     
  80.     if( theData->isSelect )
  81.         {
  82.         if( theData->selActive ) --isBackground;
  83.         theData->isSelect = 0;
  84.         theData->selActive = 0;
  85.         bounds = &( theData->selBits.bounds );
  86.         CopyBig( &( theData->selBits ), &( theData->offBits ), bounds, bounds, srcCopy, theData->selRgn );
  87.         DisposPtr( theData->selBits.baseAddr );
  88.         SetEmptyRgn( theData->selRgn );
  89.         theData->allBitsState |= bitsBadData;
  90.         bounds = &( theData->dataRect );
  91.         CopyBig( &( theData->offBits ), &( thePort->portBits ), bounds, bounds, srcCopy, NULL );
  92.         }
  93.     }
  94.  
  95. /*****************************************************************
  96. *                                                                            *
  97. *    grabSel has one ugliness in it - rather than using eraseRect or somesuch, once it has copied    *
  98. *    the selection bits it copies them back with srcXor to erase them.  This avoids all the business    *
  99. *    with setting up a grafPort.                                                    *
  100. *                                                                            *
  101. *****************************************************************/
  102.  
  103. grabSel( theData, bounds )
  104.     dataPtr        theData;
  105.     Rect            *bounds;
  106.     {
  107.     BitMap        saveBits;
  108.     RgnHandle        saveVis;
  109.     int            bytes, errno;
  110.     
  111.     ++isBackground;
  112.     theData->isSelect = -1;
  113.     theData->selActive = -1;
  114.     theData->selBits.bounds = *bounds;
  115.     theData->selBits.rowBytes = bytes = (( bounds->right - bounds->left + 15 ) >> 3 ) & -2;
  116.     theData->selBits.baseAddr = NewPtr(( long )bytes * ( bounds->bottom - bounds->top ));
  117.     if( errno = MemError() ) hardPanic( errno, memPanic );
  118.     RectRgn( theData->selRgn, bounds );
  119.     CopyBig( &( theData->offBits ), &( theData->selBits ), bounds, bounds, srcCopy, NULL );
  120.     CopyBig( &( theData->selBits ), &( theData->offBits ), bounds, bounds, srcXor, NULL );
  121.     }
  122.  
  123. /*****************************************************************
  124. *                                                                            *
  125. *    These routines  collect the sum total of the edge regions of two rectangle frames of width 1.    *
  126. *    This will generally be 3 or less rectangles each way of width 1.  These are then copied from    *
  127. *    source to dest.  The copyEdges routine replaces a copyBits of the unionRect of the two, and    *
  128. *    cuts the total time between updates dramatically - from over 7 ticks in full-screen color to    *
  129. *    approximately 3 ticks.                                                        *
  130. *                                                                            *
  131. *****************************************************************/
  132.  
  133. collectRect( collection, theRect, count, which )
  134.     int            *collection, *theRect, *count, which;
  135.     {
  136.     int            i = 0, bound, j = 0;
  137.     
  138.     bound = *count * 4;
  139.     while( i < bound && collection[ i + which ] != theRect[ which ] ) i += 4;
  140.     if( i == bound )
  141.         {
  142.         ++*count;
  143.         while( j < 4 ) collection[ i++ ] = theRect[ j++ ];
  144.         }
  145.     else {
  146.         which = 1 - which;
  147.         j = which + i;
  148.         collection[ j ] = min( collection[ j ], theRect[ which ] );
  149.         collection[ j + 2 ] = max( collection[ j + 2 ], theRect[ which + 2 ] );
  150.         }
  151.     }    
  152.  
  153. collectSides( theRect, collection, count, which )
  154.     int            *theRect, *collection, *count, which;
  155.     {
  156.     int            temp[ 4 ], i;
  157.     
  158.     for( i = 0; i < 4; ++i ) temp[ i ] = theRect[ i ];
  159.     temp[ which + 2 ] = temp[ which ] + 1;
  160.     collectRect( collection, temp, count, which );
  161.     temp[ which ] = ( temp[ which + 2 ] = theRect[ which + 2 ] ) - 1;
  162.     collectRect( collection, temp, count, which );
  163.     }
  164.  
  165. copyEdges( source, dest, oldRect, newRect, mode, mask )
  166.     BitMap        *source, *dest;
  167.     Rect            *oldRect, *newRect;
  168.     int            mode;
  169.     RgnHandle        mask;
  170.     {
  171.     Rect            edgeRects[8], temp;
  172.     int            hcount = 0, vcount = 0, i;
  173.     
  174.     collectSides( oldRect, edgeRects, &hcount, horzEdges );
  175.     if( newRect ) collectSides( newRect, edgeRects, &hcount, horzEdges );
  176.     collectSides( oldRect, &( edgeRects[ hcount ] ), &vcount, vertEdges );
  177.     if( newRect ) collectSides( newRect, &( edgeRects[ hcount ] ), &vcount, vertEdges );
  178.     for( i = hcount; i < vcount + hcount; ++i )
  179.         {
  180.         ++edgeRects[ i ].top;
  181.         --edgeRects[ i ].bottom;
  182.         }
  183.     hcount += vcount;
  184.     for( i = 0; i < hcount; ++i )
  185.         CopyBig( source, dest, &( edgeRects[ i ] ), &( edgeRects[ i ] ), mode, mask );
  186.     }
  187.  
  188. /*****************************************************************
  189. *                                                                            *
  190. *    This handles the dragging for selection of a rectangle with the marqee.  It calls doBackground    *
  191. *    occasionally, and uses the updateAnts and copyEdges routines of above.  dropSel is called at    *
  192. *    the beginning if there is a current selection, and grabSel is called at the end with the final        *
  193. *    selection information.                                                        *
  194. *                                                                            *
  195. *****************************************************************/
  196.  
  197. doSelect( theWindow, theEvent )
  198.     WindowPeek    theWindow;
  199.     EventRecord    *theEvent;
  200. {
  201.     BitMap        mainBits;
  202.     PenState        savePen;
  203.     Rect            newRect, oldRect;
  204.     Point            old, new, start;
  205.     dataHandle    theDataHand;
  206.     dataPtr        theData;
  207.     long            oldTicks = TickCount();
  208.     int            cont, shift, dh, dv, antSkew, newSkew, oldState;
  209.     
  210.     theDataHand = ( dataHandle )GetWRefCon( theWindow );
  211.     HLock( theDataHand );
  212.     theData = *theDataHand;
  213.     oldState = stopData( theData, forceStop );
  214.     dropSel( theData );
  215.     mainBits = thePort->portBits;
  216.     
  217.     start = theEvent->where;
  218.     GlobalToLocal( &start );
  219.     GetPenState( &savePen );
  220.     PenMode( patCopy );
  221.     old.h = old.v = -32768;
  222.     SetRect( &oldRect, start.h, start.v, start.h, start.v );
  223.     do {
  224.         cont = StillDown();
  225.         GetMouse( &new );
  226.         if( getModifiers() & shiftKey ) {
  227.             dh = delta( new.h, start.h );
  228.             dv = delta( new.v, start.v );
  229.             if( dv < dh ) dh = dv;
  230.             new.v = new.v > start.v ? start.v + dh : start.v - dh;
  231.             new.h = new.h > start.h ? start.h + dh : start.h - dh;
  232.         }
  233.         if( new.v != old.v || new.h != old.h ) {
  234.             newRect.top = min( new.v, start.v );
  235.             newRect.left = min( new.h, start.h );
  236.             newRect.bottom = max( new.v, start.v ) + 1;
  237.             newRect.right = max( new.h, start.h ) + 1;
  238.             SectRect( &newRect, &theData->dataRect, &newRect );
  239.             if( !EqualRect( &newRect, &oldRect )) {
  240.                 copyEdges( &( theData->offBits ), &( theData->allBits ), &oldRect, NULL, srcCopy, NULL );
  241.                 if( updateAnts( theData ))
  242.                     PenPat( getAnts( theData->antSkew ));
  243.                 SetPortBits( &( theData->allBits ));
  244.                 FrameRect( &newRect );
  245.                 SetPortBits( &mainBits );
  246.                 copyEdges( &( theData->allBits ), &mainBits, &oldRect, &newRect, srcCopy, NULL );
  247.                 old = new;
  248.                 oldRect = newRect;
  249.             }
  250.         }
  251.         if( updateAnts( theData )) {
  252.             PenPat( getAnts( theData->antSkew ));
  253.             FrameRect( &newRect );
  254.         }
  255.         doBackground( lotsElseToDo, noGray, NULL );
  256.     } while( cont );
  257.     theData->allBitsState |= bitsBadData + bitsBadSel;
  258.     SetPenState( &savePen );
  259.     if( new.v != start.v || new.h != start.h )
  260.         grabSel( theData, &newRect );
  261.     else    copyEdges( &( theData->offBits ), &mainBits, &oldRect, NULL, srcCopy, NULL );
  262.     restartData( theData, oldState );
  263.     theData->allBitsState |= bitsBadSel + bitsBadData;
  264.     theData->changed = timer();
  265.     HUnlock( theDataHand );
  266. }
  267.  
  268. /*****************************************************************
  269. *                                                                            *
  270. *                                                                            *
  271. *****************************************************************/
  272.  
  273. doSelDrag( theWindow, theEvent )
  274.     WindowPeek    theWindow;
  275.     EventRecord    *theEvent;
  276.     {
  277.     BitMap        mainBits;
  278.     PenState        savePen;
  279.     Rect            boundsRect, oldRect, newRect;
  280.     Point            old, new, start;
  281.     dataHandle    theDataHand;
  282.     dataPtr        theData;
  283.     int            dh, dv, active, cont, dir = noDir;
  284.  
  285.     theDataHand = ( dataHandle )GetWRefCon( theWindow );
  286.     HLock( theDataHand );
  287.     theData = *theDataHand;
  288.     active = theData->selActive;
  289.     oldRect = newRect = theData->selBits.bounds;
  290.     if( theEvent->modifiers & optionKey )
  291.         CopyBig( &( theData->selBits ), &( theData->offBits ), &oldRect, &oldRect, srcCopy, theData->selRgn );
  292.     theData->selActive = 0;
  293.     GetPenState( &savePen );
  294.     old = theEvent->where;
  295.     GlobalToLocal( &old );
  296.     botRight( boundsRect ) = topLeft( boundsRect ) = start = old;
  297.     SubPt( topLeft( oldRect ), &( topLeft( boundsRect )));
  298.     AddPt( topLeft( theData->dataRect ), &( topLeft( boundsRect )));
  299.     SubPt( botRight( oldRect ), &( botRight( boundsRect )));
  300.     AddPt( botRight( theData->dataRect ), &( botRight( boundsRect )));
  301.     boundsRect.right++;
  302.     boundsRect.bottom++;
  303.     mainBits = thePort->portBits;
  304.     PenMode( patCopy );
  305.     if( theEvent->modifiers & shiftKey ) dir = setMouseDir( old );
  306.     do    {
  307.         cont = StillDown();
  308.         GetMouse( &new );
  309.         if( dir == horzDir ) new.v = old.v;
  310.         else if( dir == vertDir ) new.h = old.h;
  311.         myPinRect( &boundsRect, &new );
  312.         dh = new.h - old.h;
  313.         dv = new.v - old.v;
  314.         if( dh || dv )
  315.             {
  316.             OffsetRect( &newRect, dh, dv );
  317.             OffsetRgn( theData->selRgn, dh, dv );
  318.             UnionRect( &oldRect, &newRect, &oldRect );
  319.             CopyBig( &( theData->offBits ), &( theData->allBits ), &oldRect, &oldRect, srcCopy, NULL );
  320.             CopyBig( &( theData->selBits ), &( theData->allBits ), &( theData->selBits.bounds ), &newRect, srcCopy, theData->selRgn );
  321.             PenPat( getAnts( theData->antSkew ));
  322.             SetPortBits( &( theData->allBits ));
  323.             FrameRgn( theData->selRgn );
  324.             SetPortBits( &mainBits );
  325.             CopyBig( &( theData->allBits ), &( thePort->portBits ), &oldRect, &oldRect, srcCopy, NULL );
  326.             old = new;
  327.             oldRect = newRect;
  328.             }
  329.         HUnlock( theDataHand );
  330.         doBackground( lotsElseToDo, noGray, NULL );
  331.         HLock( theDataHand );
  332.         theData = *theDataHand;
  333.         }
  334.     while( cont );
  335.     theData->selBits.bounds = newRect;
  336.     SetPenState( &savePen );
  337.     theData->selActive = active;
  338.     HUnlock( theDataHand );
  339.     }
  340.  
  341. /*****************************************************************
  342. *                                                                            *
  343. *    doBoxBrush does pencil or erasor drawing by setting the pensize and pattern.  It is the only    *
  344. *    one of these routines that draws directly onto the screen rather than drawing off-screen and    *
  345. *    copying, as it never erases old changes, but merely adds more.                            *
  346. *                                                                            *
  347. *****************************************************************/
  348.  
  349. doBoxBrush( theWindow, theEvent, size, pattern )
  350.     WindowPeek    theWindow;
  351.     EventRecord    *theEvent;
  352.     int            size;
  353.     {
  354.     BitMap        mainBits;
  355.     PenState        saveState;
  356.     Point            old, new;
  357.     RgnHandle        newClip;
  358.     dataHandle    theDataHand;
  359.     dataPtr        theData;
  360.     int            cont, oldState, dir = noDir, off;
  361.     
  362.     theDataHand = ( dataHandle )GetWRefCon( theWindow );
  363.     HLock( theDataHand );
  364.     theData = *theDataHand;
  365.     oldState = stopData( theData, forceStop );
  366.     BlockMove( theData->bases[0], theData->bases[1], theData->planeSize );
  367.     mainBits = theWindow->port.portBits;
  368.     old = theEvent->where;
  369.     GlobalToLocal( &old );
  370.  
  371.     newClip = NewRgn();
  372.     RectRgn( newClip, &( theData->dataRect ));
  373.     if( theData->isSelect )
  374.         DiffRgn( newClip, theData->selRgn, newClip );
  375.     
  376.     GetPenState( &saveState );
  377.     PenMode( patCopy );
  378.     PenSize( size, size );
  379.     off = size / 2;
  380.     SetPortBits( &( theData->offBits ));
  381.     PenPat( pattern || GetPixel( old.h, old.v ) ? &white : &black );
  382.     MoveTo( old.h - off, old.v - off );
  383.     Line( 0,0 );
  384.     SetPortBits( &mainBits );
  385.     Line( 0,0 );
  386.     if( theEvent->modifiers & shiftKey ) dir = setMouseDir( old );
  387.     do    {
  388.         cont = StillDown();
  389.         GetMouse( &new );
  390.         if( dir == horzDir ) new.v = old.v;
  391.         else if( dir == vertDir ) new.h = old.h;
  392.         if( old.h != new.h || old.v != new.v )
  393.             {
  394.             SetClip( newClip );
  395.             LineTo( new.h - off, new.v - off );
  396.             MoveTo( old.h - off, old.v - off );
  397.             SetPortBits( &( theData->offBits ));
  398.             ClipRect( &( theData->dataRect ));
  399.             LineTo( new.h - off, new.v - off );
  400.             SetPortBits( &mainBits );
  401.             old = new;
  402.             }
  403.         doBackground( someElseToDo, noGray, NULL );
  404.         }
  405.     while( cont );
  406.     
  407.     ClipRect( &( theWindow->port.portRect ));
  408.     DisposeRgn( newClip );
  409.     SetPenState( &saveState );
  410.     madeChange( theData );
  411.     restartData( theData, oldState );
  412.     HUnlock( theDataHand );
  413.     }
  414.  
  415. setMouseDir( old )
  416.     Point        old;
  417.     {
  418.     Point        new;
  419.     int        dir = 0, dh, dv;
  420.     
  421.     while( !dir && StillDown() )
  422.         {
  423.         GetMouse( &new );
  424.         dh = delta( new.h, old.h );
  425.         dv = delta( new.v, old.v );
  426.         if( dv >= 2 || dh >= 2 ) dir = dh >= dv ? horzDir : vertDir;
  427.         }
  428.     return( dir );
  429.     }
  430.  
  431. doBoxedShape( theWindow, theEvent, whichShape )
  432.     WindowPeek    theWindow;
  433.     EventRecord    *theEvent;
  434.     int            whichShape;
  435.     {
  436.     BitMap        mainBits, buffBits;
  437.     PenState        savePen;
  438.     Rect            theRect, newRect;
  439.     Point            old, new, start;
  440.     RgnHandle        maskRgn;
  441.     dataHandle    theDataHand;
  442.     dataPtr        theData;
  443.     int            oldState, angle, dh, dv, cont;
  444.     
  445.     theDataHand = ( dataHandle )GetWRefCon( theWindow );
  446.     HLock( theDataHand );
  447.     theData = *theDataHand;
  448.     oldState = stopData( theData, forceStop );
  449.     BlockMove( theData->bases[0], theData->bases[1], theData->planeSize );
  450.     mainBits = theWindow->port.portBits;
  451.     buffBits = theData->offBits;
  452.     buffBits.baseAddr = theData->bases[1];
  453.     
  454.     if( theData->isSelect ) {
  455.         maskRgn = NewRgn();
  456.         RectRgn( maskRgn, &( theData->dataRect ));
  457.         DiffRgn( maskRgn, theData->selRgn, maskRgn );
  458.     } else maskRgn = NULL;
  459.     
  460.     start = theEvent->where;
  461.     GlobalToLocal( &start );
  462.     GetPenState( &savePen );
  463.     PenMode( patCopy );
  464.     PenPat( GetPixel( start.h, start.v ) ? &white : &black );
  465.     old.h = old.v = -32768;
  466.     theRect.left = theRect.right = start.h;
  467.     theRect.top = theRect.bottom = start.v;
  468.     do    {
  469.         cont = StillDown();
  470.         GetMouse( &new );
  471.         if( getModifiers() & shiftKey )
  472.             {
  473.             dh = delta( new.h, start.h );
  474.             dv = delta( new.v, start.v );
  475.             if( whichShape != lineCurs )
  476.                 dv = dh = min( dh, dv );
  477.             else    if( dh && dv )
  478.                 {
  479.                 angle = AngleFromSlope( FixRatio( -dv, dh ));
  480.                 if( angle < 23 ) dv = 0;
  481.                 else if( angle > 67 ) dh = 0;
  482.                 else dh = dv = min( dh, dv );
  483.                 }
  484.             new.v = new.v > start.v ? start.v + dv : start.v - dv;
  485.             new.h = new.h > start.h ? start.h + dh : start.h - dh;
  486.             }
  487.         if( new.v != old.v || new.h != old.h )
  488.             {
  489.             CopyBig( &buffBits, &( theData->offBits ), &theRect, &theRect, srcCopy, NULL );
  490.             newRect.top = min( new.v, start.v );
  491.             newRect.left = min( new.h, start.h );
  492.             newRect.bottom = max( new.v, start.v ) + 1;
  493.             newRect.right = max( new.h, start.h ) + 1;
  494.             SetPortBits( &( theData->offBits ));
  495.             
  496.             if( whichShape == rectCurs )
  497.                 PaintRect( &newRect );
  498.             else    if( whichShape == elipseCurs )
  499.                 PaintOval( &newRect );
  500.             else    {
  501.                 MoveTo( start.h, start.v );
  502.                 LineTo( new.h, new.v );
  503.                 }
  504.             
  505.             SetPortBits( &mainBits );
  506.             UnionRect( &newRect, &theRect, &theRect );
  507.             SectRect( &( theData->dataRect ), &theRect, &theRect );
  508.             CopyBig( &( theData->offBits ), &mainBits, &theRect, &theRect, srcCopy, maskRgn );
  509.             theRect = newRect;
  510.             old = new;
  511.             }
  512.         doBackground( lotsElseToDo, noGray, NULL );
  513.         }
  514.     while( cont );
  515.     madeChange( theData );
  516.     if( maskRgn ) DisposeRgn( maskRgn );
  517.     restartData( theData, oldState );
  518.     SetPenState( &savePen );
  519.     HUnlock( theDataHand );
  520.     }
  521.  
  522. /*****************************************************************
  523. *                                                                            *
  524. *    These routines operate directly on the bitmap they are handed.                            *
  525. *                                                                            *
  526. *****************************************************************/
  527.  
  528. randomize( sbits, dest )
  529.     BitMap        *sbits;
  530.     register int    *dest;
  531.     {
  532.     register    int    shift = 16;
  533.     register    long    size, localseed, mult = randomMult, add = randomAdd;
  534.     
  535.     size = ( long )sbits->rowBytes * ( sbits->bounds.bottom - sbits->bounds.top ) / 2;
  536.     localseed = TickCount();
  537.     while( size )
  538.         {
  539.         localseed *= mult;
  540.         localseed += add;
  541.         *dest = ( unsigned int )( localseed >> shift );
  542.         ++dest;
  543.         --size;
  544.         }
  545.     }
  546.  
  547. eraseData( sbits, dest )
  548.     BitMap        *sbits;
  549.     register long    *dest;
  550.     {
  551.     register    long    size;
  552.     
  553.     size = ( long )sbits->rowBytes * ( sbits->bounds.bottom - sbits->bounds.top ) / 4;
  554.     while( size )
  555.         {
  556.         *dest = 0;
  557.         ++dest;
  558.         --size;
  559.         }
  560.     while( size-- ) *dest++ = 0;
  561.     }
  562.  
  563. fillData( sbits, dest )
  564.     BitMap        *sbits;
  565.     register long    *dest;
  566.     {
  567.     register    long    size, filler = -1;
  568.     
  569.     size = ( long )sbits->rowBytes * ( sbits->bounds.bottom - sbits->bounds.top ) / 4;
  570.     while( size )
  571.         {
  572.         *dest = filler;
  573.         ++dest;
  574.         --size;
  575.         }
  576.     while( size-- ) *dest++ = 0;
  577.     }
  578.  
  579. invertData( sbits, dest )
  580.     BitMap        *sbits;
  581.     register long    *dest;
  582.     {
  583.     register    long    size, *source;
  584.     
  585.     size = ( long )sbits->rowBytes * ( sbits->bounds.bottom - sbits->bounds.top ) / 4;
  586.     source = ( long * )sbits->baseAddr;
  587.     while( size )
  588.         {
  589.         *dest = ~*source;
  590.         ++dest;                /* this produces more efficient code then *…++, but in neither    */
  591.         ++source;                /* case does it actually use the postdecrement mode.        */
  592.         --size;
  593.         }
  594.     }